package com.vader.boot.aspect;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author Vader
 * @date 2022/5/25
 **/
@Slf4j
public class $JdkProxyTest implements JdkProxyTest.Foo {

    private JdkProxyTest.InvocationHandler invocationHandler;

    public $JdkProxyTest(JdkProxyTest.InvocationHandler invocationHandler) {
        this.invocationHandler = invocationHandler;
    }

    @Override
    public void foo() {
        try {
            invocationHandler.invoke(this, foo, new Object[0]);
        } catch (RuntimeException | Error e) {
            throw e;
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }

    @Override
    public int bar() {
        try {
            return (int) invocationHandler.invoke(this, bar, new Object[0]);
        } catch (RuntimeException | Error e) {
            throw e;
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }

    }

    static Method foo;
    static Method bar;

    static {
        try {
            bar = JdkProxyTest.Foo.class.getDeclaredMethod("bar");
            foo = JdkProxyTest.Foo.class.getDeclaredMethod("foo");
        } catch (RuntimeException | NoSuchMethodException e) {
            throw new Error();
        }
    }
}
